﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LDCRNewEdit.Utils;
using LDCRNewEdit.Services;
using LDCRNewEdit.Model;

namespace LDCRNewEdit.UI.地图编辑.场景地图设计
{
    public partial class SceneEventForm : Form
    {
        private SceneData sceneData;        //场景数据
        private string sceneFilename = string.Empty;    //存档目录

        private Point CurPoint; //当前选中的坐标

        private int XScale = 24;        //格子半高
        private int YScale = 12;        //格子半宽
        private bool ShowGrid = true;   //是否显示网格
        private bool ShowBlock = true;     //是否显示障碍点
        private bool ShowEvent = true;  //显示事件位置
        private bool ShowJump = true;   //显示跳转场景

        private int ScrollX = 0;
        private int ScrollY = 0;
        private bool IsChangeMap = true;

        public SceneEventForm()
        {
            InitializeComponent();
        }

        private void UpdatePictureBox()
        {
            if (sceneData == null || sceneData.SceneMap == null)
                return;

            SceneMap sceneMap = sceneData.SceneMap;

            int sh = Screen.PrimaryScreen.Bounds.Height;

            int sw = Screen.PrimaryScreen.Bounds.Width;

            Bitmap img = null;
            Graphics g = null;

            this.pictureBox1.Location = new Point(0, 0);
            if (IsChangeMap)
            {

                ScrollX = 0;
                ScrollY = 0;

                this.pictureBox1.Size = new Size(sceneMap.MapWidth * XScale * 2, sceneMap.MapHeight * YScale * 2);

                if (this.pictureBox1.Size.Width > sw)
                {
                    this.panel2.HorizontalScroll.Value = this.pictureBox1.Size.Width / 2;
                    ScrollX = this.pictureBox1.Size.Width / 2;
                }
                else
                {
                    this.panel2.HorizontalScroll.Value = 0;
                }

                if (this.pictureBox1.Size.Height > sh)
                {
                    this.panel2.VerticalScroll.Value = this.pictureBox1.Size.Height / 2;
                    ScrollY = this.pictureBox1.Size.Height / 2;
                }
                else
                {
                    this.panel2.VerticalScroll.Value = 0;
                }

                IsChangeMap = false;
            }


            //img = new Bitmap(map.MapWidth * XScale * 2, map.MapHeight * YScale * 2);
            int w = sw;
            int h = sh;
            if (this.pictureBox1.Size.Width - ScrollX < w)
            {
                w = this.pictureBox1.Size.Width - ScrollX;
                if (w <= 0)
                {
                    return;
                }
            }
            if (this.pictureBox1.Size.Height - ScrollY < h)
            {
                h = this.pictureBox1.Size.Height - ScrollY;
                if (h <= 0)
                {
                    return;
                }
            }
            img = new Bitmap(w, h);
            if (this.pictureBox1.Image != null)
            {
                this.pictureBox1.Image.Dispose();
            }
            g = Graphics.FromImage(img);




            //显示地面
            foreach (SceneGroundLv sl in sceneMap.GroundList)
            {
                if (sl.X + sceneMap.XOff - ScrollX >= -sl.W && sl.X + sceneMap.XOff - ScrollX + sl.W <= w + sl.W && sl.Y + sceneMap.YOff - ScrollY >= -sl.H && sl.Y + sceneMap.YOff - ScrollY <= h + sl.H)
                    g.DrawImage(sl.Image, sl.X + sceneMap.XOff - ScrollX, sl.Y + sceneMap.YOff - ScrollY, sl.Image.Width, sl.Image.Height);
            }


            //建筑排序
            sceneMap.BuilList.Sort();
            foreach (SceneBuildLv sl in sceneMap.BuilList)
            {
                if (sl.X + sceneMap.XOff - ScrollX >= -sl.W && sl.X + sceneMap.XOff - ScrollX + sl.W <= w + sl.W && sl.Y + sceneMap.YOff - ScrollY >= -sl.H && sl.Y + sceneMap.YOff - ScrollY <= h + sl.H)
                {
                    g.DrawImage(sl.Image, sl.X + sceneMap.XOff - ScrollX, sl.Y + sceneMap.YOff - ScrollY, sl.Image.Width, sl.Image.Height);
                }
            }

            //显示障碍点
            if (ShowBlock)
            {
                SolidBrush brush = new SolidBrush(Color.FromArgb(96, Color.Red));
                foreach (Point p in sceneMap.BlockSet)
                {
                    g.FillPolygon(brush, convertXY(p).ToArray());
                }
            }

            //显示CurPoint
            if (CurPoint.X > 0 && CurPoint.Y > 0)
            {
                SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Blue));
                g.FillPolygon(brush, convertXY(CurPoint).ToArray());
            }


            //绘制网格

            if (ShowGrid)
            {
                Pen p = new Pen(Color.Cyan);

                for (int i = 0; i <= sceneMap.MapWidth; i++)
                {
                    g.DrawLine(p, new Point((sceneMap.MapWidth + i) * XScale - ScrollX, i * YScale - ScrollY), new Point(i * XScale - ScrollX, (sceneMap.MapHeight + i) * YScale - ScrollY));

                }

                for (int i = 0; i <= sceneMap.MapHeight; i++)
                {
                    g.DrawLine(p, new Point((sceneMap.MapWidth - i) * XScale - ScrollX, i * YScale - ScrollY), new Point(sceneMap.MapWidth * XScale * 2 - i * XScale - ScrollX, (sceneMap.MapHeight + i) * YScale - ScrollY));
                }
            }


            //事件格子
            if (ShowEvent)
            {
                SolidBrush brush = new SolidBrush(Color.FromArgb(96, Color.Orange));
                foreach (Point p in sceneData.SceneNPCList.Keys)
                {
                    g.FillPolygon(brush, convertXY(p).ToArray());
                }
            }
            //跳转格子
            if (ShowJump)
            {
                SolidBrush brush = new SolidBrush(Color.FromArgb(96, Color.Azure));
                foreach (Point p in sceneData.SceneJumpList.Keys)
                {
                    g.FillPolygon(brush, convertXY(p).ToArray());
                }
            }
            g.Dispose();

            pictureBox1.Image = img;

            pictureBox1.Update();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Resources.GetPath("SceneMap");
            ofd.Filter = "*.smap|*.smap";
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                sceneData = new SceneData();
                sceneData.SceneMapPath = ofd.FileName.Replace(Resources.GamePath, "");

                //读取文件
                sceneData.SceneMap = SceneMapService.LoadSceneMap(ofd.FileName);
                //加载地面文件
                sceneData.SceneMap.GroundList.AddRange(SceneMapService.LoadGroundMap(Resources.GamePath + sceneData.SceneMap.GroundPath));


                this.labelSceneName.Text = sceneData.SceneMap.Name;
                this.comboBox1.SelectedIndex = 0;



                IsChangeMap = true;
                UpdatePictureBox();

            }
        }

        private void SceneEventForm_Load(object sender, EventArgs e)
        {
            this.MouseWheel += new MouseEventHandler(PictureBox_MouseWheel);
        }
        void PictureBox_MouseWheel(object sender, MouseEventArgs e)
        {
            ScrollY -= e.Delta;
            if (ScrollY < 0) ScrollY = 0;
            if (ScrollY > this.panel2.VerticalScroll.Maximum) ScrollY = this.panel2.VerticalScroll.Maximum;
            this.panel2.VerticalScroll.Value = ScrollY;
            UpdatePictureBox();
        }

        private void panel2_Scroll(object sender, ScrollEventArgs e)
        {
            if (ScrollOrientation.HorizontalScroll == e.ScrollOrientation)
            {
                ScrollX = e.NewValue;
            }
            else
            {
                ScrollY = e.NewValue;
            }

            UpdatePictureBox();
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (sceneData == null || sceneData.SceneMap == null)
                return;

            SceneMap sceneMap = sceneData.SceneMap;
            
            Point p = convertPoint(e.X, e.Y);
            this.labelGrid.Text = p.X + "," + p.Y;
            
        }

        /// <summary>
        /// 像素转为XY坐标
        /// </summary>
        /// <param name="px"></param>
        /// <returns></returns>
        private Point convertPoint(int x, int y)
        {
            SceneMap sceneMap = sceneData.SceneMap;
            Point p = new Point();
            x += ScrollX;
            y += ScrollY;
            p.X = (int)(((double)(x - sceneMap.MapWidth * XScale) / XScale) + (double)(y)
                    / YScale) / 2;
            p.Y = (int)(((double)(y) / YScale - (double)(x - sceneMap.MapWidth * XScale)
                    / XScale)) / 2;

            return p;
        }

        /// <summary>
        /// 把XY坐标转为像素
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        private List<Point> convertXY(Point p)
        {
            SceneMap sceneMap = sceneData.SceneMap;

            List<Point> list = new List<Point>();
            list.Add(new Point(sceneMap.MapWidth * XScale + (p.X - p.Y) * XScale - ScrollX, (p.X + p.Y) * YScale - ScrollY));
            list.Add(new Point(sceneMap.MapWidth * XScale + (p.X - 1 - p.Y) * XScale - ScrollX, (p.Y + 1 + p.X) * YScale - ScrollY));
            list.Add(new Point(sceneMap.MapWidth * XScale + (p.X - p.Y) * XScale - ScrollX, (p.Y + 2 + p.X) * YScale - ScrollY));
            list.Add(new Point(sceneMap.MapWidth * XScale + (p.X + 1 - p.Y) * XScale - ScrollX, (p.Y + 1 + p.X) * YScale - ScrollY));

            return list;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (sceneData != null)
            {
                //选择保存文件
                /*
                if (string.IsNullOrEmpty(sceneFilename))
                {
                    SaveFileDialog sfd = new SaveFileDialog();
                    sfd.Filter = "*.sdata|*.sdata";
                    sfd.InitialDirectory = Resources.GetPath("SceneData");
                    if (sfd.ShowDialog() == DialogResult.OK)
                    {
                        string filename = sfd.FileName;
                        if (filename.LastIndexOf(".sdata") == -1)
                        {
                            filename += ".sdata";
                        }

                        sceneFilename = filename;
                    }
                }*/

                if (string.IsNullOrEmpty(sceneFilename))
                {
                    //默认是以场景名称命名的
                    string name = System.IO.Path.GetFileName(Resources.GamePath + sceneData.SceneMapPath);
                    name = name.Substring(0, name.LastIndexOf("."));
                    sceneFilename = Resources.GetPath("SceneData") + name + ".sdata";
                }
                SceneMapService.SaveSceneData(sceneFilename, sceneData);
                MessageBox.Show("保存成功!");
                
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                CurPoint = convertPoint(e.X, e.Y);
                this.labelCurPosition.Text = string.Format("{0},{1}", CurPoint.X, CurPoint.Y);

                UpdatePictureBox();
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (sceneData != null)
            {
                if (sceneData.SceneNPCList.ContainsKey(CurPoint))
                {
                    if (MessageBox.Show("已经在当前为位置存在事件，是否直接编辑？", "提示", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK)
                    {
                        SceneNPCForm f = new SceneNPCForm();
                        SceneNPC nc = f.ShowDialogEvent(sceneData.SceneNPCList[CurPoint]);
                        if (nc != null)
                        {
                            sceneData.SceneNPCList[CurPoint] = nc;
                            UpdatePictureBox();
                        }
                    }

                    return;
                }
                else  //新增事件
                {
                    SceneNPC snpc = new SceneNPC();
                    snpc.X = (short)CurPoint.X;
                    snpc.Y = (short)CurPoint.Y;
                    SceneNPCForm form = new SceneNPCForm();
                    snpc = form.ShowDialogEvent(snpc);

                    if (snpc != null)
                    {
                        sceneData.SceneNPCList[CurPoint] = snpc;
                        UpdatePictureBox();
                    }
                }

            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (sceneData != null)
            {
                if (!sceneData.SceneNPCList.ContainsKey(CurPoint))
                {
                    MessageBox.Show("当前位置并不存在事件!", "警告");
                    return;
                }
                else
                {
                    sceneData.SceneNPCList.Remove(CurPoint);
                    UpdatePictureBox();

                    MessageBox.Show("删除成功!");
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Resources.GetPath("SceneData");
            ofd.Filter = "*.sdata|*.sdata";
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                sceneData = SceneMapService.LoadSceneData(ofd.FileName);

                //读取建筑文件
                sceneData.SceneMap = SceneMapService.LoadSceneMap(Resources.GamePath + sceneData.SceneMapPath);
                //加载地面文件
                sceneData.SceneMap.GroundList.AddRange(SceneMapService.LoadGroundMap(Resources.GamePath + sceneData.SceneMap.GroundPath));


                this.labelSceneName.Text = sceneData.SceneMap.Name;
                this.comboBox1.SelectedIndex = sceneData.OpenFlag;



                IsChangeMap = true;
                UpdatePictureBox();
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (sceneData != null)
            {
                if (!sceneData.SceneJumpList.ContainsKey(CurPoint))
                {
                    MessageBox.Show("当前位置并不存在场景跳转!", "警告");
                    return;
                }
                else
                {
                    sceneData.SceneJumpList.Remove(CurPoint);
                    UpdatePictureBox();

                    MessageBox.Show("删除成功!");
                }
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (sceneData != null)
            {
                if (sceneData.SceneJumpList.ContainsKey(CurPoint))
                {
                    if (MessageBox.Show("已经在当前为位置存在跳转场景，是否直接编辑？", "提示", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK)
                    {
                        SceneJumpForm f = new SceneJumpForm();
                        SceneJump jp = f.ShowJumpDialog(sceneData.SceneJumpList[CurPoint]);
                        if (jp != null)
                        {
                            sceneData.SceneJumpList[CurPoint] = jp;
                            UpdatePictureBox();
                        }
                    }

                    return;
                }
                else  //新增跳转
                {
                    SceneJump jump = new SceneJump();
                    jump.X = (short)CurPoint.X;
                    jump.Y = (short)CurPoint.Y;
                    SceneJumpForm form = new SceneJumpForm();
                    jump = form.ShowJumpDialog(jump);

                    if (jump != null)
                    {
                        sceneData.SceneJumpList[CurPoint] = jump;
                        UpdatePictureBox();
                    }
                }

            }
        }

        
    }
}
